﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using UnityEngine;


namespace RStudio.UIFramwork
{
    /// <summary>
    /// 模组|UI队列
    /// </summary>
    public class UIModuleQueue
    {
        [Description("事件队列")] public readonly Queue<UIEventArgs> uiQueue = new();
        [Description("事件更新")] public Action<UIEventArgs> OnUIProcessed;
        [Description("处理进程")] private bool _isProcessing;
        [Description("游戏协程")] private readonly UIModuleQueueCoroutinue _coroutine;


        /// <summary>
        /// 单帧处理的最大数量
        /// </summary>
        public int MaxPerFrame { get; private set; }

        /// <summary>
        /// 单次处理时的最小帧间隔
        /// </summary>
        public int MinFrameInterval { get; private set; }


        public UIModuleQueue()
        {
            this._isProcessing = false;
            this.SetFrameLimit(3, 30);

            _coroutine = new GameObject("UIModuel Queue Coroutinue").AddComponent<UIModuleQueueCoroutinue>();
            GameObject.DontDestroyOnLoad(_coroutine.gameObject);
        }

        /// <summary>
        /// 配置帧处理限制
        /// </summary>
        /// <param name="maxPerFrame">单帧处理的最大数量</param>
        /// <param name="minFrameIntervalMs">单次处理时的最小帧间隔</param>
        public void SetFrameLimit(int maxPerFrame, int minFrameIntervalMs)
        {
            this.MaxPerFrame = Mathf.Max(1, maxPerFrame);
            this.MinFrameInterval = Mathf.Max(16, minFrameIntervalMs); // 最低约60FPS
        }

        /// <summary>
        /// 添加到队列
        /// </summary>
        public void Enqueue(UIEventArgs args)
        {
            uiQueue.Enqueue(args);

            if (!_isProcessing)
            {
               _coroutine.StartCoroutine(IProcessQueue());
            }
        }

        /// <summary>
        /// 队列自处理
        /// </summary>
        private IEnumerator IProcessQueue()
        {
            _isProcessing = true;
            var _lastProcessTime = Time.realtimeSinceStartup * 1000; // 转换为毫秒

            while (uiQueue.Count > 0)
            {
                int processedCount = 0;
                float currentTime = Time.realtimeSinceStartup * 1000;
                float elapsedMs = currentTime - _lastProcessTime;

                // 确保满足最小帧间隔（上限控制：不能处理太快）
                if (elapsedMs < MinFrameInterval)
                {
                    yield return new WaitForSeconds((MinFrameInterval - elapsedMs) / 1000f);
                }

                // 每帧处理不超过最大数量（下限控制：不能处理太多）
                while (uiQueue.Count > 0 && processedCount < MaxPerFrame)
                {
                    UIEventArgs current = uiQueue.Dequeue();
                    OnUIProcessed?.Invoke(current);

                    processedCount++;
                }

                _lastProcessTime = Time.realtimeSinceStartup * 1000;
                yield return null; // 等待一帧，让渲染线程有机会执行
            }

            _isProcessing = false;
        }
    }


    public class UIModuleQueueCoroutinue : MonoBehaviour { }
}
